package com.lpx.blog.util;

import com.lpx.blog.config.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import jakarta.servlet.http.HttpServletResponse;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;

import java.net.URLEncoder;
import java.util.concurrent.TimeUnit;

@Component
public class MinioUtil {

	private static final Logger logger = LoggerFactory.getLogger(MinioUtil.class);

	@Autowired
	private MinioClient minioClient;

	@Autowired
	private MinioConfig configuration;

	/**
	 * 判断bucket是否存在，不存在则创建
	 */
	public boolean existBucket(String bucketName) {
		boolean exists;
		try {
			exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
			if (!exists) {
				minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
				exists = true;
			}
			logger.info("Bucket {} exists: {}", bucketName, exists);
		} catch (Exception e) {
			logger.error("Error checking or creating bucket {}: {}", bucketName, e.getMessage());
			exists = false;
		}
		return exists;
	}

	/**
	 * 删除bucket
	 */
	public Boolean removeBucket(String bucketName) {
		try {
			minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
		} catch (Exception e) {
			logger.error("Error removing bucket {}: {}", bucketName, e.getMessage());
			return false;
		}
		return true;
	}

	/**
	 * 上传文件
	 *
	 * @param file     文件
	 * @param fileName 文件名称
	 */
	public void upload(MultipartFile file, String fileName) {
		try (InputStream inputStream = file.getInputStream()) {
			minioClient.putObject(PutObjectArgs.builder()
					.bucket(configuration.getBucketName())
					.object(fileName)
					.stream(inputStream, file.getSize(), -1)
					.contentType(file.getContentType())
					.build());
			logger.info("File {} uploaded successfully to bucket {}", fileName, configuration.getBucketName());
		} catch (Exception e) {
			logger.error("Error uploading file {}: {}", fileName, e.getMessage());
		}
	}

	/**
	 * 获取文件访问地址（有过期时间）
	 *
	 * @param fileName 文件名称
	 * @param time     时间
	 * @param timeUnit 时间单位
	 */
	public String getExpireFileUrl(String fileName, int time, TimeUnit timeUnit) {
		try {
			return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
					.method(Method.GET)
					.bucket(configuration.getBucketName())
					.object(fileName)
					.expiry(time, timeUnit).build());
		} catch (Exception e) {
			logger.error("Error getting fileUrl:  {}", e.getMessage());
		}
		return null;
	}

	/**
	 * 获取文件访问地址
	 *
	 * @param fileName 文件名称
	 */
	public String getFileUrl(String fileName) {
		try {
			return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
					.method(Method.GET)
					.bucket(configuration.getBucketName())
					.object(fileName)
					.build()
			);
		} catch (Exception e) {
			logger.error("Error downloading file {}", e.getMessage());
		}
		return null;
	}

	/**
	 * 下载文件
	 *
	 * @param fileName 文件名称
	 */
	public void download(HttpServletResponse response, String fileName) {
		InputStream in = null;
		try {
			StatObjectResponse stat = minioClient.statObject(StatObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
			response.setContentType(stat.contentType());
			response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));

			in = minioClient.getObject(GetObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
			IOUtils.copy(in, response.getOutputStream());
			logger.info("File {} downloaded successfully", fileName);
		} catch (Exception e) {
			logger.error("Error downloading file {}: {}", fileName, e.getMessage());
		} finally {
			if (in != null) {
				try {
					in.close();
				} catch (IOException e) {
					logger.error("Error closing input stream: {}", e.getMessage());
				}
			}
		}
	}

	/**
	 * 删除文件
	 *
	 * @param fileName 文件名称
	 */
	public void delete(String fileName) {
		try {
			minioClient.removeObject(RemoveObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
			logger.info("File {} deleted successfully from bucket {}", fileName, configuration.getBucketName());
		} catch (Exception e) {
			logger.error("Error deleting file {}: {}", fileName, e.getMessage());
		}
	}

}